//////////////////////////////////////////////////////////////////////////
//
// GAM204
// Octree Manager
// Octree.h
// 
// Grant Johnson
// Qantm College
// 27/10/2010
//
//////////////////////////////////////////////////////////////////////////

#ifndef OCTREE_H
#define OCTREE_H

#include <vector>
#include "Node.h"
#include "Renderparams.h"
#include "Renderer.h"

class Text;

class Octree
{
public:
	
	Octree();
	//Second constructor, setup the max number of objects per node
	Octree(int a_max);
	~Octree();
	
	//////////////////////////////////////////////////////////////////////////
	// Create the root node, the entire octree, as well as setup the debug text
	//
	// Paramaters:
	// a_bottomLeft, the bottomLeft vector of the root node
	// a_center, the center vector of the root node
	// a_topRight, the top right vector of the root node
	//
	// Returns void
	//
	//////////////////////////////////////////////////////////////////////////
	void CreateOctree(AABB a_aabb);	

	//////////////////////////////////////////////////////////////////////////
	// Traverse through the octree, checking each node against the frustum
	// of the first camera (this is for debug only, normally would be the active
	// camera). If the node has children and isn't empty, it calls AddObjectToRenderer()
	// Else if it's a branch node, it will traverse through its children
	//
	// Paramaters:
	// a_pNode, a pointer to the node to use
	// 
	//
	// Returns void
	//
	//////////////////////////////////////////////////////////////////////////
	void TraverseAndRender(Node* a_pNode);

	void FillRenderList();

	//////////////////////////////////////////////////////////////////////////
	// Get the debug text of the octree
	//
	// Paramaters:
	// None
	//
	// Returns a pointer to the debug text 
	//
	//////////////////////////////////////////////////////////////////////////
	Text* GetDebugText() { return m_pDebugText; }

	//////////////////////////////////////////////////////////////////////////
	// Returns whether or not to render in wireframe mode
	//
	// Paramaters:
	// a_val, the new value for the wireframe rendering mode
	//
	// Returns void
	//
	//////////////////////////////////////////////////////////////////////////
	void SetWireframeRendering(bool a_val) { m_wireframeRendering = a_val; }

	//////////////////////////////////////////////////////////////////////////
	// Get wireframe rendering mode
	//
	// Paramaters:
	// None
	//
	// Returns true if going to render in wireframe
	// Returns false if going to render in solid
	//
	//////////////////////////////////////////////////////////////////////////
	bool GetWireframeRendering() { return m_wireframeRendering; }

	void Traverse(Node* a_pNode);

private:
	//Max number of objects before splitting the node
	int m_maxObjects;
	
	//Root node
	Node* m_pRootNode;

	Renderer* m_pRenderer;

	//---------------
	//DEBUG VARIABLES
	//---------------

	//Number of nodes that contain objects
	int m_numNodesWithObjects;

	//How deep the tree is 
	int m_depth;

	//Toggle between solid and wireframe rendering
	bool m_wireframeRendering;

	//Debug text
	Text* m_pDebugText;

	int m_numCollisionChecks;
};

#endif //OCTREE_H